import os

import paramiko as paramiko


def exists_remote_path(sftp_client, path):
    """
    判断远程路径是否存在
    :param sftp_client: SFTPClient对象
    :param path: 远程路径
    :return: True/False
    """
    try:
        sftp_client.stat(path)
        return True
    except IOError:
        return False


def make_remote_dir(sftp_client, path):
    """
    创建远程路径
    :param sftp_client: SFPTClient对象
    :param path: 需要创建的远程路径
    """
    paths = path.split('/')
    remote_path = '/'
    for p in paths:
        if p is not None and p is not '':
            remote_path = remote_path + '/' + p
            if not exists_remote_path(sftp_client, remote_path):
                sftp_client.mkdir(remote_path)


class SftpTransporter:
    """SFTP文件上传"""

    transport: paramiko.Transport = None
    sftp_client: paramiko.SFTPClient = None
    host: str = None
    port: int = None
    name: str = None

    def __init__(self, host, port=22, username='root', password=''):
        """
        :param basestring host: 远程主机地址
        :param int port: 远程主机端口
        :param basestring username: 登录名
        :param basestring password: 登录密码
        """
        self.host = host
        self.port = port
        try:
            self.transport = paramiko.Transport((host, port))
            self.transport.connect(username=username, password=password)
            self.sftp_client = paramiko.SFTPClient.from_transport(self.transport)
        except BaseException as e:
            print(str(e))
            exit(0)

    def upload(self, localfile, remotepath) -> (bool, str):
        """
        上传文件
        :param basestring localfile: 本地文件路径
        :param basestring remotepath: 远程文件夹路径
        :return: True:上传成功，False：上传失败
        """
        filename = os.path.basename(localfile)
        remotefile = remotepath + ('/' if not remotepath.endswith('/') else '') + filename
        try:
            if not self.exists_remote_path(remotepath):
                self.make_remote_dir(remotepath)
            self.sftp_client.put(localfile, remotefile)
            return True, remotefile
        except BaseException as e:
            print(str(e))
            return False, remotefile

    def close(self):
        """
        关闭上传通道
        """
        self.sftp_client.close()
        self.transport.close()

    def exists_remote_path(self, path) -> bool:
        """
        判断远程路径是否存在
        :param path: 远程路径
        :return: True/False
        """
        try:
            self.sftp_client.stat(path)
            return True
        except IOError:
            return False

    def make_remote_dir(self, path):
        """
        创建远程路径
        :param path: 需要创建的远程路径
        """
        paths = path.split('/')
        remote_path = '/'
        for p in paths:
            if p is not None and p is not '':
                remote_path = remote_path + '/' + p
                if not self.exists_remote_path(remote_path):
                    self.sftp_client.mkdir(remote_path)
